package demo.DataStrucAndAlgo.Linked;

/**
 * @Auther: hjy(lc))
 * @Date: 2022/7/23-07-23-9:52
 * @Description：demo.DataStrucAndAlgo 单链表内部类递归实现
 * 解决既要访问数据便利，又要维持封装性，那么就启用Java方便的内部类
 */
interface ILink<E>{        //统一了链表操作规范，并在隐藏操作细节的同时暴露了链表操作的方法
    public void add(E e);     //链表数据增加
    public int count();       //获取链表元素个数
    public boolean isEmpty();   //空集合判断
    public Object[] toArray();  //返回链表数据
    public E get(int index);    //根据索引取得数据
    public void set(int index, E data);  //修改链表数据
    public boolean contains(E data);     //数据内容查询
    public void remove(E data);          //删除链表数据：1、删除根节点，2、删除子节点
    public void clean();                 //清空链表数据
    public void reverseList();
}
class LinkImple<E> implements ILink<E>{

    private int count;
    private Node root;
    private int foot;
    private Object[] returnData;

    private class Node{
        private E data;
        private Node next;
        public Node(E data){
            this.data = data;
        }
        public void addNode(Node newNode){         //结点存储下一个结点操作
            if(this.next == null){          //当前对象的下一个节点内存为空时，把传入的节点对象赋给当前对象的下一个节点内存中
                this.next = newNode;
            }else{                        //当前对象的下一个节点内存非空时，通过递归调用来实现节点对象的保存
                this.next.addNode(newNode);
            }
        }
        public void toArrayNode(){
            LinkImple.this.returnData[LinkImple.this.foot++] = this.data;
            if(this.next!=null){
                this.next.toArrayNode();
            }
        }
        public E getNode(int index){
            if(LinkImple.this.foot++ == index){
                return this.data;
            }else{
                return this.next.getNode(index);    //将此处得到的数据再用一个return返回到调用处

            }
        }
        public void setNode(int index,E data){
            if(LinkImple.this.foot++ == index){
                this.data = data;
            }else{
                this.next.setNode(index,data);
            }
        }
        public boolean containNode(E data){
            if(data.equals(this.data)){
                return true;
            }else if(this.next == null){
                return false;
            }else{
                return this.next.containNode(data);
            }
        }
        public void removeNode(Node previous, E data){          //删除子节点
            if(data.equals(this.data)){
                previous.next = this.next;
            }else if(this.next != null){
                this.next.removeNode(this,data);
            }
        }
    }
    @Override
    public void add(E e) {
        if(e == null){
            return;
        }
        Node newNode = new Node(e);
        if(this.root == null){
            root = newNode;
        }else{
            this.root.addNode(newNode);
        }
        count++;
    }

    @Override
    public int count() {
        return this.count;
    }

    @Override
    public boolean isEmpty() {
        return this.count==0;
    }

    @Override
    public Object[] toArray() {
        if(this.isEmpty()){
            return null;
        }
        this.foot = 0;
        this.returnData = new Object[this.count];
        this.root.toArrayNode();
        return returnData;
    }

    @Override
    public E get(int index) {
        if(index >= count){
            return null;
        }
        this.foot = 0;
        return this.root.getNode(index);
    }

    @Override
    public void set(int index, E data) {     //根据索引修改元素的值
        if(index >= count){
            return ;
        }
        this.foot = 0;
        this.root.setNode(index,data);
    }

    @Override
    public boolean contains(E data) {
        if(data == null){
            return false;
        }
        return this.root.containNode(data);
    }

    @Override
    public void remove(E data) {
        if(data == null){
            return ;
        }
        if(data.equals(this.root.data)){//删除根节点
            this.root = this.root.next;
        }else{
            this.root.removeNode(this.root,data);
        }
        count--;
    }

    @Override
    public void clean() {
        this.root = null;
        count = 0;
    }


    @Override
    public void reverseList() {
        if(root == null || root.next == null){
            return;
        }
        Node next,temp=root,Newroot = root;
        int coun = count;
        root.next = null;
        while(coun > 1){
            temp = Newroot.next;
            next = temp;
            temp.next = Newroot;

            Newroot = next;
            coun--;
        }
        root = temp;
    }
}
public class Linked_Inner_Re {
    public static void main(String[] args) {
        ILink <String>link=new LinkImple <String> ();
        System.out.println("初始化数据："+link.count()+"\t 是否为空集合："+link.isEmpty());
        link.add("hello");
        link.add("world");
        link.add("!");
        System.out.println("结果数据："+link.count()+"\t 是否为空集合："+link.isEmpty());
        Object[] result=link.toArray();
        for(Object temp:result){
            System.out.println(temp);
        }
        System.out.println("---------------------根据索引获取链表元素--------------------");
        System.out.println(link.get(1));
        System.out.println("---------------------根据索引修改链表元素--------------------");
        link.set(1,"WORLD");
        System.out.println(link.get(1));
        System.out.println("---------------------根据数组盘判断是否存在对应链表元素--------------------");
        System.out.println(link.contains("WORLD"));

        System.out.println("-------------------翻转链表------------------------");
        link.reverseList();
        Object[] resultC=link.toArray();
        for(Object temp:resultC){
            System.out.println(temp);
        }

        System.out.println("---------------------根据自动内容删除对应链表元素--------------------");
        link.remove("WORLD");
        Object[] resultB=link.toArray();
        for(Object temp:resultB){
            System.out.println(temp);
        }
        System.out.println("---------------------清空链表元素--------------------");
        link.clean();
        System.out.println(link.isEmpty());
    }
}
